import { PropType, defineComponent, computed, Slot } from "vue";
import './index.scss'
import { renderFunc, RequiredTreeNodeOptions } from "./types";
import RenderNode from './render'
import CheckBox from '../checkbox/checkbox'
import { CustomEventFuncType } from "../utils/type";
export default defineComponent({
  name: 'TreeNode',
  props: {
    node: { type: Object as PropType<RequiredTreeNodeOptions>, required: true },
    iconSlot: Function as PropType<Slot>,
    render: Function as PropType<renderFunc>,
    showCheckBox: { type: Boolean, default: false },
    checkStrictly: { type: Boolean, default: false },
    onToggleExpand: Function as CustomEventFuncType<RequiredTreeNodeOptions>,
    onSelectChange: Function as CustomEventFuncType<RequiredTreeNodeOptions>,
    onCheckChange: Function as CustomEventFuncType<[boolean, RequiredTreeNodeOptions]>,
  },
  emits: ['toggle-expand', 'select-change', 'check-change'],
  setup(props, { emit, expose}) {
    const handleExpand = () => {
      emit('toggle-expand', props.node)
    }
    const textCls = computed(() => {
      let result = 'node-title';
      if (props.node.selected && !props.showCheckBox) {
        result += ' selected';
      }
      if (props.node.disabled) {
        result += ' disabled';
      }
      return result;
    });
    const halfChecked = computed(() => {
      let result = false;
      if (!props.checkStrictly && props.node.hasChildren) {
        const { children } = props.node
        const checkedChildren = children.filter(item => item.checked);
        result = checkedChildren.length > 0 && checkedChildren.length < children.length;
      }
      return result;
    });
    const handleCheckChange = (checked: boolean) => {
      emit('check-change', [checked, props.node]);
    };
    const handleSelect = (evt: MouseEvent) => {
      evt.stopPropagation();
      if (!props.node.disabled) {
        emit('select-change', props.node)
      }
    }

    const renderArrow = ():JSX.Element | null => {
      const slot = props.iconSlot ? props.iconSlot(props.node.loading) : props.node.loading ? <i class="iconfont iconloading ico-loading" /> : <i class="iconfont iconExpand" />
      return <div class={["node-arrow", props.node.expanded ? 'expanded' : '']}>
          { props.node.hasChildren ? slot : null }
        </div>
    }

    const renderContent = ():JSX.Element | null => {
      if (props.showCheckBox) {
        return <CheckBox
          class="node-content node-checked"
          disabled={ props.node.disabled }
          modelValue={ props.node.checked }
          halfChecked={ halfChecked.value }
          onChange={ handleCheckChange }>
          { normalContent() }
        </CheckBox>
      }
      return <div class="node-content node-text" onClick={ handleSelect }>{ normalContent() }</div>
    }

    const normalContent = (): JSX.Element => {
      return props.render ? <RenderNode render={ props.render } node={ props.node} /> : <span class={ textCls.value }>{props.node.name}</span>
    }

    expose({
      node: props.node,
      halfChecked: () => halfChecked.value,
    })
    return () => {
      return (
        <div class="ant-tree-node" style={{paddingLeft: props.node.level * 18 + 'px'}} onClick={ handleExpand }>
          { renderArrow() }
          { renderContent() }
          
        </div>
      )
    }
  }
})